package gel;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.junit.Before;
import org.junit.Test;
import robocode.Bullet;
import robocode.HitByBulletEvent;
import robocode.ScannedRobotEvent;
import robocode.exception.RobotException;

/**
 * Tests various methods of the Menehune robot.
 * 
 * @author George Lee
 *
 */
public class TestMenehuneMethods {
  /** Instance of the Menehune robot. */
  private Menehune robot;
  /** Error for our turn angle comparison. */
  private static final double EPSILON = 0.0001;

  /**
   * Initialize our test case.
   * 
   * @throws Exception if initialization fails (should not occur).
   */
  @Before
  public void setUp() throws Exception {
    robot = new Menehune();
  }

  /**
   * Tests that the getPerpendicularTurnAngle method of Menehune works as expected.
   */
  @Test
  public void testPerpendicularTurnAngle() {
    double eventBearing = 0;
    assertEquals("Checking turn angle for bearing 0", eventBearing + 90.0, robot
        .getPerpendicularTurnAngle(eventBearing), EPSILON);

    eventBearing = 135;
    assertEquals("Checking negative turn angle for bearing 90", (eventBearing + 90.0) * -1.0, robot
        .getPerpendicularTurnAngle(eventBearing), EPSILON);
  }

  /**
   * Tests that we register bullet hits properly.
   */
  @Test
  public void testOnHitByBullet() {
    int hitCount = 0;
    // Initialize a bullet with some bogus values.
    Bullet bullet = new Bullet(0, 0, 0, 1, "Foo", "Menehune", true, 0);
    HitByBulletEvent event = new HitByBulletEvent(0, bullet);
    assertEquals("Checking no hits registered to Menehune.", hitCount, robot.getHitCount());

    robot.onHitByBullet(event);
    hitCount++;
    assertEquals("Checking that one hit registered on Menehune.", hitCount, robot.getHitCount());

    Bullet fatBullet = new Bullet(0, 0, 0, 3, "Foo", "Menehune", true, 0);
    event = new HitByBulletEvent(0, fatBullet);
    robot.onHitByBullet(event);
    hitCount += 2;
    assertEquals("Checking that a powerful hit registers twice on Menehune.", hitCount, robot
        .getHitCount());
  }

  /**
   * Tests that we start tracking a robot.
   */
  @Test
  public void testOnScannedRobot() {
    // Initialize an event with bogus values.
    ScannedRobotEvent event = new ScannedRobotEvent("Foo", 100, 0, 10, 0, 0);
    try {
      robot.onScannedRobot(event);
      fail("Should have thrown exception where we attempted to move or fire.");
    }
    catch (RobotException e) {
      assertEquals("Testing scanned robot name.", event.getName(), robot.getScannedRobotName());
      assertEquals("Testing robot mode.", Menehune.RobotMode.FIRE_MODE, robot.getMode());
    }
  }
}
